<template>
  <!-- Header: Display Name and IP -->
  <div class="info-header">
    <span class="name">{{ longname }}</span>
    <span class="ip">{{ ip }}</span>
    <!-- <el-button @click="change" style="padding: 0 20px">change</el-button> -->
  </div>
  <div style="height: 100%">
    <div class="container">
      <div class="left-side" id="network-details" style="width: 100%; height: 100%"></div>
      <div class="right-side">
        <div class="clean">
          <div class="load-chart" id="load-chart" style="height: 100%"></div>
        </div>
        <div class="graph-modal">
          <div v-if="selectedGraph === 'input'">
            <Input :data="ioData" ref="inputChart" />
          </div>
          <div v-if="selectedGraph === 'output'">
            <Output :data="ioData" ref="outputChart" />
          </div>
          <div v-if="selectedGraph === 'cpu'">
            <CPU :data="cpuData" ref="cpuChart" />
          </div>
          <div v-if="selectedGraph === 'gpu'">
            <Gpu :data="gpuData" ref="gpuChart" />
          </div>
          <div v-if="selectedGraph === 'gpurate'">
            <GpuRate :data="gpuRate" ref="gpuRateChart" />
          </div>
          <div v-if="selectedGraph === 'memory'">
            <Memory :data="memData" ref="memoryChart" />
          </div>
          <div v-if="selectedGraph === 'diskread'">
            <DiskRead :data="diskRead" ref="diskReadChart" />
          </div>
          <div v-if="selectedGraph === 'diskwrite'">
            <DiskWrite :data="diskWrite" ref="diskWriteChart" />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import CPU from "./CPUGraph.vue";
import Memory from "./MemoryGraph.vue";
import Gpu from "./GpuGraph.vue";
import Input from "./InputGraph.vue";
import Output from "./OutputGraph.vue";
import GpuRate from "./GpuRateGraph.vue";
import DiskRead from "./DiskReadGraph.vue";
import DiskWrite from "./DiskWriteGraph.vue";
import axios from "axios";
import * as echarts from "echarts";
import { loadConfig } from "@/utils/config";

export default {
  components: {
    CPU,
    Memory,
    Gpu,
    Input,
    Output,
    GpuRate,
    DiskRead,
    DiskWrite,
  },
  props: {
    name: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      data: [],
      cpuData: [],
      memData: [],
      gpuData: [],
      gpuRate: [],
      diskRead: [],
      diskWrite: [],
      ioData: [],
      jsonData: {},
      filteredInstances: {},
      ip: "",
      longname: "",
      intervalId: null,
      showGraphModal: true,
      selectedGraph: "cpu",
      currentState: 0,
      ws: null,
      message: "",
      loadChart: null,
      currentLoad: 0.5, // 当前负载值
      resourceData: [
        { value: 0.1, name: "通" },
        { value: 0.2, name: "算" },
        { value: 0.2, name: "存" },
      ],
      option: [
        {
          // tooltip: {},
          series: [
            {
              type: "graph",
              layout: "none",
              data: [
                { name: "通", x: 200, y: 100, symbol: "image://" + require("@/assets/icon/rect.png"), symbolSize: [90, 90], label: { fontSize: 30 } },
                { name: "算", x: 100, y: 200, symbol: "image://" + require("@/assets/icon/rect.png"), symbolSize: [90, 90], label: { fontSize: 30 } },
                { name: "存", x: 300, y: 200, symbol: "image://" + require("@/assets/icon/rect.png"), symbolSize: [90, 90], label: { fontSize: 30 } },
                { name: "Input", x: 150, y: 0, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [100, 100] },
                { name: "Output", x: 250, y: 0, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [100, 100] },
                { name: "CPU", x: 0, y: 150, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [100, 100] },
                { name: "GPU", x: 0, y: 250, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [100, 100] },
                { name: "GPU %", x: 80, y: 310, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [100, 100] },
                { name: "Memory", x: 400, y: 150, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [100, 100] },
                { name: "Disk Wr", x: 400, y: 250, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [100, 100] },
                { name: "Disk Rd", x: 320, y: 310, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [100, 100] },
              ],
              links: [
                { source: "通", target: "算", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
                { source: "算", target: "存", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
                { source: "存", target: "通", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
                { source: "通", target: "Input", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
                { source: "通", target: "Output", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
                { source: "算", target: "CPU", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
                { source: "算", target: "GPU", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
                { source: "算", target: "GPU %", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
                { source: "存", target: "Memory", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
                { source: "存", target: "Disk Wr", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
                { source: "存", target: "Disk Rd", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
              ], // 初始化为空
              label: {
                show: true,
                position: "inside",
                formatter: "{b}",
                color: "black",
                fontSize: 22,
              },
              lineStyle: {
                curveness: 0,
                width: 2,
                color: "white",
                opacity: 1,
              },
            },
          ],
        },
      ],
    };
  },
  methods: {
    connectWebSocket() {
      // 创建 WebSocket 连接
      this.ws = new WebSocket("ws://10.112.51.79:38414/ws");

      // 监听消息
      this.ws.onmessage = (event) => {
        console.log("Received:", event.data);
        this.message = event.data; // 显示接收到的消息
        if (this.message.includes("U 1")) {
          this.change(1);
        } else if (this.message.includes("H 1 2")) {
          this.change(0);
        }
      };

      // 监听 WebSocket 连接关闭
      this.ws.onclose = () => {
        console.log("WebSocket connection closed");
      };

      // 监听 WebSocket 错误
      this.ws.onerror = (error) => {
        console.error("WebSocket error:", error);
      };
    },
    sendMessage() {
      if (this.ws && this.ws.readyState === WebSocket.OPEN) {
        // 发送消息
        this.ws.send("Hello from Vue!");
      }
    },
    initLoadChart() {
      const container = document.getElementById("load-chart");
      if (container) {
        this.loadChart = echarts.init(container);
        this.updateLoadChart();
      }
    },

    updateLoadChart() {
      if (!this.loadChart) return;

      // 计算各资源占比
      const tong = this.resourceData.find((d) => d.name === "通").value;
      const suan = this.resourceData.find((d) => d.name === "算").value;
      const cun = this.resourceData.find((d) => d.name === "存").value;

      const option = {
        tooltip: {
          trigger: "item",
          formatter: (params) => {
            return `${params.name}: ${params.value}%`;
          }
        },
        legend: {
          show: true,
          orient: "horizontal",
          bottom: 0,
          left: "center",
          data: ["负载", "通", "算", "存"],
          textStyle: {
            color: "#fff",
            fontSize: 18,
          },
          itemWidth: 30,
          itemHeight: 10,
          itemGap: 20,
        },
        series: [
          {
            name: "负载占比",
            type: "pie",
            selectedMode: "single",
            radius: ["0%", "50%"],
            center: ["50%", "50%"],
            avoidLabelOverlap: true,
            itemStyle: {
              borderRadius: 10,
              borderColor: "#fff",
              borderWidth: 2,
            },
            label: {
              show: true,
              position: "center",
              formatter: `${(this.currentLoad * 100).toFixed(1)}%`,
              fontSize: 30,
              fontWeight: "bold",
              color: "#fff",
            },
            labelLine: {
              show: false,
            },
            data: [
              {
                value: (this.currentLoad * 100).toFixed(1),
                name: "负载",
                itemStyle: { color: this.currentLoad < 0.6 ? "#91cc75" : this.currentLoad < 0.8 ? "#fac858" : "#e34a18" },
              },
              {
                value: ((1 - this.currentLoad) * 100).toFixed(1),
                name: "负载-剩余",
                itemStyle: { color: "transparent" },
              },
            ],
          },
          {
            name: "资源占比",
            type: "pie",
            selectedMode: "single",
            radius: ["60%", "75%"],
            center: ["50%", "50%"],
            avoidLabelOverlap: true,
            itemStyle: {
              borderColor: "#fff",
              borderWidth: 2,
            },
            label: {
              show: true,
              formatter: (params) => {
                if (!params.name.includes("剩余")) {
                  return `${params.name}\n${params.value}%`;
                } else {
                  return "";
                }
              },
              fontSize: 20,
              fontWeight: "bold",
              color: "#fff",
            },
            labelLine: {
              smooth: true,
              length: 10,
              length2: 10,
            },
            data: [
              { value: (tong * 100).toFixed(1), name: "通", itemStyle: { color: tong < 0.6 ? "#91cc75" : tong < 0.8 ? "#fac858" : "#e34a18" } },
              { value: ((1 - tong) * 100).toFixed(1), name: "通-剩余", itemStyle: { color: "transparent", borderWidth: 1 } },
              { value: (suan * 100).toFixed(1), name: "算", itemStyle: { color: suan < 0.6 ? "#91cc75" : suan < 0.8 ? "#fac858" : "#e34a18" } },
              { value: ((1 - suan) * 100).toFixed(1), name: "算-剩余", itemStyle: { color: "transparent", borderWidth: 1 } },
              { value: (cun * 100).toFixed(1), name: "存", itemStyle: { color: cun < 0.6 ? "#91cc75" : cun < 0.8 ? "#fac858" : "#e34a18" } },
              { value: ((1 - cun) * 100).toFixed(1), name: "存-剩余", itemStyle: { color: "transparent", borderWidth: 1 } },
            ],
          },
        ],
      };

      this.loadChart.setOption(option);
    },

    async fetchData() {
      try {
        let that = this;
        const config = await loadConfig();
        const apiUrl = config.apiUrl;
        await axios.get(`${apiUrl}/get_nf_data?nf=${this.name}`).then(function (res) {
          that.data = res.data;
        });
        await axios.get(`${apiUrl}/getDB?table=prediction_data`).then(function (res) {
          const data = res.data[res.data.length-1]; // 获取最新的数据
          if (that.name === "upf-0") {
            that.currentLoad = data.upf0_load || 0.1;
            that.resourceData = [
              { value: data.upf0_comm || 0.1, name: "通" },
              { value: data.upf0_comp || 0.1, name: "算" },
              { value: data.upf0_cach || 0.1, name: "存" },
            ]
          } else if (that.name === "upf-1") {
            that.currentLoad = data.upf1_load || 0.1;
            that.resourceData = [
              { value: data.upf1_comm || 0.1, name: "通" },
              { value: data.upf1_comp || 0.1, name: "算" },
              { value: data.upf1_cach || 0.1, name: "存" },
            ]
          } else if (that.name === "upf-2") {
            that.currentLoad = data.upf2_load || 0.1;
            that.resourceData = [
              { value: data.upf2_comm || 0.1, name: "通" },
              { value: data.upf2_comp || 0.1, name: "算" },
              { value: data.upf2_cach || 0.1, name: "存" },
            ]
          } else if (that.name === "upf-3") {
            that.currentLoad = data.upf3_load || 0.1;
            that.resourceData = [
              { value: data.upf3_comm || 0.1, name: "通" },
              { value: data.upf3_comp || 0.1, name: "算" },
              { value: data.upf3_cach || 0.1, name: "存" },
            ]
          }
          that.currentLoad = that.currentLoad.toFixed(3);
          for (let i = 0; i < that.resourceData.length; i++) {
            that.resourceData[i].value = that.resourceData[i].value.toFixed(3);
          }
          that.updateLoadChart();
        });
        this.cpuData = this.data.phy_cpu_list || 0;
        this.memData = this.data.phy_mem_list || 0;
        this.gpuData = this.data.gpu_list || 0;
        this.ioData = this.data.net_io_list || 0;
        this.gpuRate = this.data.gpu_rate || 0;
        this.diskRead = this.data.disk_read || 0;
        this.diskWrite = this.data.disk_write || 0;
        this.ip = this.data.ip || 0;
        this.longname = this.data.name;
        // console.log(this.gpuRate);
        if (this.showGraphModal) this.updateChartData();
      } catch (error) {
        console.error("Failed to fetch data:", error);
      }
    },
    initChart() {
      const container = document.getElementById("network-details");
      if (container) {
        this.myChart = echarts.init(container);
        this.myChart.setOption(this.option[0]);
      }
      this.refreshCharts();
      // 添加点击事件
      this.myChart.on("click", this.handleNodeClick);
    },
    destroyChart() {
      if (this.myChart) {
        this.myChart.dispose(); // 销毁图表实例
      }
    },
    handleNodeClick(params) {
      // this.selectedGraph = params.name.toLowerCase(); // 更新点击的节点名称
      const componentMap = {
        CPU: "CPU",
        Memory: "Memory",
        GPU: "Gpu",
        Input: "Input",
        Output: "Output",
        "GPU %": "GpuRate",
        "Disk Wr": "DiskWrite",
        "Disk Rd": "DiskRead",
      };
      this.selectedGraph = componentMap[params.name].toLowerCase();
      if (this.selectedGraph) {
        // this.selectedGraph = componentName;
        this.showGraphModal = true;
      }
    },
    refreshCharts() {
      console.log("refreshCharts");
      const charts = ["inputChart", "outputChart", "cpuChart", "gpuChart", "gpuRateChart", "memoryChart", "diskReadChart", "diskWriteChart"];

      charts.forEach((chartName) => {
        if (this.$refs[chartName] && this.$refs[chartName].refreshChart) {
          this.$refs[chartName].refreshChart();
        }
      });
    },
    updateChartData() {
      this.myChart.setOption({
        tooltip: {
          trigger: 'item',
          formatter: (params) => {
            // 根据节点类型返回不同的内容
            if (params.dataType === 'node') {
              const node = params.data;
              if (node.name === 'CPU') {
                return `CPU使用率: ${this.cpuData[this.cpuData.length - 1]}m`;
              } else if (node.name === 'GPU') {
                return `GPU使用量: ${this.gpuData[this.gpuData.length - 1]}Mi`;
              } else if (node.name === 'Memory') {
                return `内存使用: ${this.memData[this.memData.length - 1]}Mi`;
              } else if (node.name === 'Input') {
                return `输入流量: ${this.ioData[this.ioData.length - 1].toFixed(2)}Mb/s`;
              } else if (node.name === 'Output') {
                return `输出流量: ${this.ioData[this.ioData.length - 1].toFixed(2)}Mb/s`;
              } else if (node.name === 'GPU %') {
                return `GPU利用率: ${this.gpuRate[this.gpuRate.length - 1]}%`;
              } else if (node.name === 'Disk Wr') {
                return `磁盘写入: ${(this.diskWrite[this.diskWrite.length - 1] / 1000).toFixed(2)}kB`;
              } else if (node.name === 'Disk Rd') {
                return `磁盘读取: ${(this.diskRead[this.diskRead.length - 1] / 1000).toFixed(2)}kB`;
              } else {
                return node.name;
              }
            } else if (params.dataType === 'edge') {
              return `连接: ${params.data.source} → ${params.data.target}`;
            }
            return params.name;
          },
          backgroundColor: '#fff',
          borderColor: 'black',
          borderWidth: 1,
          padding: [10, 15],
          textStyle: {
            color: 'black',
            fontSize: 18
          }
        },
        series: [
          {
            type: "graph",
            layout: "none",
            data: [
              { name: "通", x: 200, y: 100, symbol: "image://" + require("@/assets/icon/rect.png"), symbolSize: [120, 120], label: { fontSize: 40 } },
              { name: "算", x: 100, y: 200, symbol: "image://" + require("@/assets/icon/rect.png"), symbolSize: [120, 120], label: { fontSize: 40 } },
              { name: "存", x: 300, y: 200, symbol: "image://" + require("@/assets/icon/rect.png"), symbolSize: [120, 120], label: { fontSize: 40 } },
              { name: "Input", x: 150, y: 0, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [120, 120] },
              { name: "Output", x: 250, y: 0, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [120, 120] },
              { name: "CPU", x: 0, y: 150, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [120, 120] },
              { name: "GPU", x: 0, y: 250, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [120, 120] },
              { name: "GPU %", x: 80, y: 310, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [120, 120] },
              { name: "Memory", x: 400, y: 150, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [120, 120] },
              { name: "Disk Wr", x: 400, y: 250, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [120, 120] },
              { name: "Disk Rd", x: 320, y: 310, symbol: "image://" + require("@/assets/icon/circle.png"), symbolSize: [120, 120] },
            ].map((item) => {
              if (item.name === "CPU") {
                item.label = { show: true, position: "inside", formatter: `CPU\n${this.cpuData[this.cpuData.length - 1]}m` };
              } else if (item.name === "GPU") {
                item.label = { show: true, position: "inside", formatter: `GPU\n${this.gpuData[this.gpuData.length - 1]}Mi` };
              } else if (item.name === "Memory") {
                item.label = { show: true, position: "inside", formatter: `Memory\n${this.memData[this.memData.length - 1]}Mi` };
              } else if (item.name === "Input") {
                item.label = { show: true, position: "inside", formatter: `Input\n${this.ioData[this.ioData.length - 1].toFixed(2)}Mb/s` };
              } else if (item.name === "Output") {
                item.label = { show: true, position: "inside", formatter: `Output\n${this.ioData[this.ioData.length - 1].toFixed(2)}Mb/s` };
              } else if (item.name == "GPU %") {
                item.label = { show: true, position: "inside", formatter: `GPU %\n${this.gpuRate[this.gpuRate.length - 1]}%` };
              } else if (item.name == "Disk Wr") {
                item.label = { show: true, position: "inside", formatter: `Disk Wr\n${(this.diskWrite[this.diskWrite.length - 1] / 1000).toFixed(2)}kB` };
              } else if (item.name == "Disk Rd") {
                item.label = { show: true, position: "inside", formatter: `Disk Rd\n${(this.diskRead[this.diskRead.length - 1] / 1000).toFixed(2)}kB` };
              }
              return item;
            }),
            links: [
              { source: "通", target: "算", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
              { source: "算", target: "存", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
              { source: "存", target: "通", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
              { source: "通", target: "Input", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
              { source: "通", target: "Output", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
              { source: "算", target: "CPU", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
              { source: "算", target: "GPU", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
              { source: "算", target: "GPU %", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
              { source: "存", target: "Memory", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
              { source: "存", target: "Disk Wr", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
              { source: "存", target: "Disk Rd", label: { show: true, formatter: "", position: "middle", rotate: 0, color: "white" } },
            ],
            label: {
              show: true,
              position: "inside",
              formatter: "{b}",
              color: "black",
              fontSize: 22,
            },
            lineStyle: {
              curveness: 0,
              width: 2,
              color: "white",
              opacity: 1,
            },
          },
        ],
      });
    },
    showGraph(type) {
      this.selectedGraph = type;
      this.showGraphModal = true;
    },
    closeGraph() {
      this.showGraphModal = false;
      this.selectedGraph = null;
      if (this.myChart) {
        this.myChart.dispose();
      }
      // 重新初始化图表
      this.$nextTick(() => {
        this.initChart();
      });
    },
  },
  mounted() {
    this.$nextTick(() => {
      this.initChart();
      this.initLoadChart();
      this.fetchData();
      this.intervalId = setInterval(this.fetchData, 1000);
      this.showGraphModal = true;
    });
  },
  beforeUnmount() {
    if (this.intervalId) {
      clearInterval(this.intervalId);
    }
    if (this.myChart) {
      this.myChart.dispose(); // 销毁图表实例
    }
    if (this.loadChart) {
      this.loadChart.dispose();
    }
    // 关闭 WebSocket 连接
    if (this.ws) {
      this.ws.close();
    }
  },
};
</script>

<style scoped>
.container {
  display: grid;
  grid-template-columns: 3fr 2fr;
  /* 左侧2份，右侧1份 */
  width: 100%;
  height: 100%;
}

.left-side {
  width: 90%;
  height: 100%;
}

.right-side {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
}

.clean {
  flex: 1;
  height: 80%;
  width: 100%;
}

.clean img {
  width: 100%;
  height: 80%;
}

.graph-modal {
  margin-top: 15%;
  flex: 1;
  height: 100%;
}

.info-header {
  position: absolute;
  z-index: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px 20px;
  background-color: transparent;
  font-size: 24px;
  font-weight: bold;
  border-radius: 10px;
  max-width: 100%;
  text-shadow: 1px 1px 2px #000;
}

.name,
.ip {
  display: inline-block;
  margin: 0 10px;
  font-weight: bolder;
}

.name {
  color: #4caf50;
}

.ip {
  color: #4caf50;
}

.info-header .name::before {
  content: "Name: ";
  font-weight: bold;
}

.info-header .ip::before {
  content: "IP: ";
  font-weight: bold;
}

.info-header:hover {
  background-color: #444;
  transition: background-color 0.3s;
  cursor: pointer;
}
</style>
